package com.codeworker.app.data;

import android.content.Context;
import android.os.Environment;

import androidx.annotation.NonNull;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import androidx.sqlite.db.SupportSQLiteDatabase;

import com.codeworker.app.data.dao.BillDao;
import com.codeworker.app.data.dao.DailyRecordDao;
import com.codeworker.app.data.dao.MonthlyRecordDao;
import com.codeworker.app.data.dao.PropertyDao;
import com.codeworker.app.data.entity.Bill;
import com.codeworker.app.data.entity.DailyRecord;
import com.codeworker.app.data.entity.MonthlyRecord;
import com.codeworker.app.data.entity.Property;

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 数据库配置
 */
@Database(
        entities = {Bill.class, Property.class, DailyRecord.class, MonthlyRecord.class},
        version = 1,
        exportSchema = false)
public abstract class AccountRoomDatabase extends RoomDatabase {

    private final static String DATABASE_NAME = "account_database.db";
    public final static File DATA_FILE = new File(Environment.getDataDirectory(),
            "data/com.codeworker.app/databases/" + DATABASE_NAME);
    private final static String BACK_UP_FILE_PATH = "backup/com.codeworker.app";
    public final static File EXTERN_DATA_FILE_DIR = new File(Environment.getExternalStorageDirectory(),
            BACK_UP_FILE_PATH);
    public final static File EXTERN_DATA_FILE = new File(EXTERN_DATA_FILE_DIR, DATABASE_NAME);
    public final static String EXTERN_DATA_FILE_NAME = BACK_UP_FILE_PATH + "/" + DATABASE_NAME;

    public abstract BillDao billDao();

    public abstract PropertyDao propertyDao();

    public abstract DailyRecordDao dailyRecordDao();

    public abstract MonthlyRecordDao monthlyRecordDao();

    // marking the instance as volatile to ensure atomic access to the variable
    private static volatile AccountRoomDatabase INSTANCE;
    private static final int NUMBER_OF_THREADS = 4;
    public static final ExecutorService databaseWriteExecutor =
            Executors.newFixedThreadPool(NUMBER_OF_THREADS);

    public static AccountRoomDatabase getDatabase(final Context context) {
        if (INSTANCE == null) {
            synchronized (AccountRoomDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AccountRoomDatabase.class, DATABASE_NAME)
                            .addCallback(sRoomDatabaseCallback)
                            .allowMainThreadQueries()
                            .build();
                }
            }
        }
        return INSTANCE;
    }

    public static void closeDatabase() {
        if (INSTANCE != null && INSTANCE.isOpen()) {
            INSTANCE.close();
            INSTANCE = null;
        }
    }

    /**
     * Override the onCreate method to populate the database.
     * For this sample, we clear the database every time it is created.
     */
    private static final RoomDatabase.Callback sRoomDatabaseCallback = new RoomDatabase.Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);

            databaseWriteExecutor.execute(() -> {
                // Populate the database in the background.
                // If you want to start with more words, just add them.
                INSTANCE.billDao();
                INSTANCE.dailyRecordDao();
                INSTANCE.monthlyRecordDao();
                PropertyDao propertyDao = INSTANCE.propertyDao();
                propertyDao.insert(new Property("现金", 0, ""));
            });
        }
    };
}
